home *** CD-ROM | disk | FTP | other *** search
/ Cre@te Online 2000 December / Cre@teOnline CD05.iso / MacSoft / XML Instance.sea / XML Instance / Required / plugins / HTMLWindow.jar / horst / View.class (.txt) < prev    next >
Encoding:
Java Class File  |  2000-03-18  |  18.2 KB  |  888 lines

  1. package horst;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Font;
  5. import java.awt.FontMetrics;
  6. import java.awt.Graphics;
  7. import java.awt.Insets;
  8. import java.awt.Rectangle;
  9. import java.awt.Shape;
  10. import java.awt.Toolkit;
  11. import java.util.Enumeration;
  12. import java.util.Stack;
  13. import java.util.Vector;
  14.  
  15. public class View {
  16.    public static final int Y_AXIS = 0;
  17.    public static final int X_AXIS = 1;
  18.    public static final int LEFT_ALIGN = 0;
  19.    public static final int CENTER_ALIGN = 1;
  20.    public static final int RIGHT_ALIGN = 2;
  21.    static URLClassLoader m_classLoader = new URLClassLoader();
  22.    protected View[] m_children;
  23.    protected Rectangle m_bounds;
  24.    protected Insets m_insets;
  25.    protected Element m_elem;
  26.    protected View m_parent;
  27.    protected HTMLPane m_container;
  28.    protected int m_alignment;
  29.    protected ViewLine[] m_rows;
  30.    protected View[] m_floaters;
  31.    protected boolean m_bCanWrap;
  32.    protected int m_prefWidth;
  33.    protected int m_prefHeight;
  34.    protected int m_minWidth;
  35.    protected int m_minHeight;
  36.    private Vector m_floats = new Vector();
  37.    private int m_totalSpan;
  38.    private int m_yPos;
  39.    private int m_leftRenderingArea;
  40.    private int m_targetWidth;
  41.    private ViewLine m_line;
  42.    private Vector m_layoutRows = new Vector();
  43.    private View m_view;
  44.    private Stack m_viewStack = new Stack();
  45.    private Vector m_pushedViews = new Vector();
  46.  
  47.    public View(View parent, Element e, HTMLPane container) {
  48.       this.m_container = container;
  49.       this.m_parent = parent;
  50.       this.m_elem = e;
  51.       this.m_bCanWrap = true;
  52.       this.m_insets = new Insets(0, 0, 0, 0);
  53.       this.m_bounds = new Rectangle();
  54.       this.m_children = new View[0];
  55.       this.m_rows = new ViewLine[0];
  56.       this.m_floaters = new View[0];
  57.       this.m_alignment = 0;
  58.       this.m_prefWidth = -1;
  59.       this.m_prefHeight = -1;
  60.       this.m_minWidth = -1;
  61.       this.m_minHeight = -1;
  62.       this.init();
  63.    }
  64.  
  65.    protected boolean alignInBounds() {
  66.       return false;
  67.    }
  68.  
  69.    private boolean canBackTrack() {
  70.       if (this.m_view.getElementType() == 101) {
  71.          int sz = this.m_line.vector.size();
  72.          if (sz <= 1) {
  73.             return false;
  74.          }
  75.  
  76.          View v = (View)this.m_line.vector.elementAt(sz - 2);
  77.          if (v.getElementType() != 101) {
  78.             v = this.m_line.getLastView();
  79.             this.m_totalSpan -= v.getPreferredSpan(1);
  80.             this.m_viewStack.push(v);
  81.             this.m_viewStack.push(this.m_view);
  82.             return true;
  83.          }
  84.       }
  85.  
  86.       int idx = this.m_line.findNBSPBreak();
  87.       if (idx != -1) {
  88.          int sz = this.m_line.vector.size();
  89.          View v = (View)this.m_line.vector.elementAt(sz - 2);
  90.          if (v.getElementType() != 101) {
  91.             for(int i = sz - 1; i >= idx; --i) {
  92.                v = this.m_line.removeView(i);
  93.                this.m_totalSpan -= v.getPreferredSpan(1);
  94.                this.m_viewStack.push(v);
  95.             }
  96.  
  97.             this.m_viewStack.push(this.m_view);
  98.             return true;
  99.          }
  100.       }
  101.  
  102.       return false;
  103.    }
  104.  
  105.    protected boolean canSplit(int width) {
  106.       return false;
  107.    }
  108.  
  109.    protected boolean contains(int x, int y) {
  110.       return this.getBounds().contains(x, y);
  111.    }
  112.  
  113.    protected ViewLine createALine(int x, int y, int width) {
  114.       ViewLine row = new ViewLine();
  115.       row.x = x;
  116.       row.y = y;
  117.       row.alignment = this.m_alignment;
  118.       row.parent = this;
  119.       row.lineWidth = width;
  120.       return row;
  121.    }
  122.  
  123.    protected void drawDebugBox(Graphics g, Color c) {
  124.    }
  125.  
  126.    protected void drawFocusBox(Graphics g) {
  127.       g.setColor(Color.black);
  128.       Utilities.drawDottedRectangle(g, this.m_bounds.x, this.m_bounds.y, this.m_bounds.width, this.m_bounds.height);
  129.    }
  130.  
  131.    protected View elementToView(Element e) {
  132.       if (this.m_elem == e) {
  133.          return this;
  134.       } else {
  135.          for(int row = 0; row < this.m_rows.length; ++row) {
  136.             View[] views = this.m_rows[row].getViews();
  137.  
  138.             for(int j = 0; j < views.length; ++j) {
  139.                View v = views[j].elementToView(e);
  140.                if (v != null) {
  141.                   return v;
  142.                }
  143.             }
  144.          }
  145.  
  146.          return null;
  147.       }
  148.    }
  149.  
  150.    protected synchronized void flushResources() {
  151.       for(int i = 0; i < this.m_children.length; ++i) {
  152.          this.m_children[i].flushResources();
  153.       }
  154.  
  155.    }
  156.  
  157.    protected void forceLayout() {
  158.       if (this.m_container != null) {
  159.          this.m_container.forceLayout();
  160.       }
  161.  
  162.    }
  163.  
  164.    protected Object getAttribute(Object key) {
  165.       return this.m_elem.getAttributes().get(key);
  166.    }
  167.  
  168.    public Rectangle getBounds() {
  169.       return this.m_bounds;
  170.    }
  171.  
  172.    protected int getDescent() {
  173.       return 0;
  174.    }
  175.  
  176.    protected HTMLDocument getDocument() {
  177.       return this.m_container.getDocument();
  178.    }
  179.  
  180.    protected int getElementType() {
  181.       return this.m_elem.getType();
  182.    }
  183.  
  184.    protected Font getFont() {
  185.       Font f = this.m_elem.getFont();
  186.       if (f == null) {
  187.          f = new Font("Serif", 0, 12);
  188.       }
  189.  
  190.       return f;
  191.    }
  192.  
  193.    protected FontMetrics getFontMetrics() {
  194.       return Toolkit.getDefaultToolkit().getFontMetrics(this.getFont());
  195.    }
  196.  
  197.    protected int getMinimumSpan(int axis) {
  198.       if (axis != 1) {
  199.          return 0;
  200.       } else if (this.m_minWidth != -1) {
  201.          return this.m_minWidth;
  202.       } else {
  203.          boolean bLastNoBreakSpace = false;
  204.          int maxRowSpan = 0;
  205.          int span = 0;
  206.          boolean bNewline = false;
  207.          int nChildren = this.m_children.length;
  208.  
  209.          for(int i = 0; i < nChildren; ++i) {
  210.             View v = this.m_children[i];
  211.             if (bNewline || v.isNewlineView() || !bLastNoBreakSpace && this.m_bCanWrap && !v.isNoBreakSpace()) {
  212.                maxRowSpan = Math.max(maxRowSpan, span);
  213.                span = 0;
  214.                bNewline = false;
  215.             }
  216.  
  217.             if (v instanceof TextView) {
  218.                boolean bCanWrap = this.m_bCanWrap;
  219.                if (bLastNoBreakSpace || i != nChildren - 1 && this.m_children[i + 1] instanceof NBSPView) {
  220.                   bCanWrap = false;
  221.                }
  222.  
  223.                if (bCanWrap) {
  224.                   span += ((TextView)v).getMaximumTokenLength();
  225.                } else {
  226.                   span += v.getMinimumSpan(1);
  227.                }
  228.             } else {
  229.                span += v.getMinimumSpan(1);
  230.             }
  231.  
  232.             bNewline = v.isNextViewOnNewLine();
  233.             bLastNoBreakSpace = v.isNoBreakSpace();
  234.          }
  235.  
  236.          maxRowSpan = Math.max(maxRowSpan, span);
  237.          this.m_minWidth = maxRowSpan + this.m_insets.left + this.m_insets.right;
  238.          return this.m_minWidth;
  239.       }
  240.    }
  241.  
  242.    protected int getPreferredSpan(int axis) {
  243.       if (axis != 1) {
  244.          return 0;
  245.       } else if (this.m_prefWidth != -1) {
  246.          return this.m_prefWidth;
  247.       } else {
  248.          int maxRowSpan = 0;
  249.          int span = 0;
  250.          boolean bNewline = false;
  251.  
  252.          for(int i = 0; i < this.m_children.length; ++i) {
  253.             View v = this.m_children[i];
  254.             if (v.isNewlineView() || bNewline) {
  255.                maxRowSpan = Math.max(maxRowSpan, span);
  256.                span = 0;
  257.                bNewline = false;
  258.             }
  259.  
  260.             span += v.getPreferredSpan(1);
  261.             bNewline = v.isNextViewOnNewLine();
  262.          }
  263.  
  264.          maxRowSpan = Math.max(maxRowSpan, span);
  265.          this.m_prefWidth = maxRowSpan + this.m_insets.left + this.m_insets.right;
  266.          return this.m_prefWidth;
  267.       }
  268.    }
  269.  
  270.    protected Element getRootElement() {
  271.       return this.m_container.getRootElement();
  272.    }
  273.  
  274.    protected String getToolTipText() {
  275.       return "";
  276.    }
  277.  
  278.    protected void init() {
  279.    }
  280.  
  281.    protected void invalidate() {
  282.       this.m_prefWidth = -1;
  283.       this.m_prefHeight = -1;
  284.       this.m_minWidth = -1;
  285.       this.m_minHeight = -1;
  286.  
  287.       for(View parent = this.m_parent; parent != null; parent = parent.m_parent) {
  288.          parent.invalidate();
  289.       }
  290.  
  291.    }
  292.  
  293.    protected boolean isAttributeDefined(Integer att) {
  294.       return this.m_elem.getAttributes().containsKey(att);
  295.    }
  296.  
  297.    protected boolean isBlockView() {
  298.       return this.isNewlineView() && this.isNextViewOnNewLine();
  299.    }
  300.  
  301.    protected boolean isContainerView() {
  302.       return true;
  303.    }
  304.  
  305.    protected boolean isDisplayableView() {
  306.       return true;
  307.    }
  308.  
  309.    protected boolean isFloater() {
  310.       return false;
  311.    }
  312.  
  313.    protected boolean isFloaterClearer() {
  314.       return false;
  315.    }
  316.  
  317.    protected boolean isLink() {
  318.       return this.m_elem.getAttribute("href") != null;
  319.    }
  320.  
  321.    protected boolean isNewlineView() {
  322.       return false;
  323.    }
  324.  
  325.    protected boolean isNextViewOnNewLine() {
  326.       return false;
  327.    }
  328.  
  329.    boolean isNoBreakSpace() {
  330.       return false;
  331.    }
  332.  
  333.    protected boolean isPlaceHolderView() {
  334.       return false;
  335.    }
  336.  
  337.    protected boolean isSelfContained() {
  338.       return false;
  339.    }
  340.  
  341.    protected boolean isSplittable() {
  342.       return false;
  343.    }
  344.  
  345.    protected boolean isWrappable() {
  346.       return false;
  347.    }
  348.  
  349.    protected Rectangle layout(int x, int y, int width, LayoutInfo info) {
  350.       info.setPageBreak(y);
  351.       this.m_bounds.setBounds(x, y, 0, 0);
  352.       if (this.m_children.length == 0) {
  353.          return this.m_bounds;
  354.       } else {
  355.          this.m_floats.removeAllElements();
  356.          this.m_totalSpan = 0;
  357.          this.m_viewStack.removeAllElements();
  358.  
  359.          for(int i = this.m_children.length - 1; i >= 0; --i) {
  360.             this.m_viewStack.push(this.m_children[i]);
  361.          }
  362.  
  363.          this.m_view = (View)this.m_viewStack.pop();
  364.          this.m_yPos = y + this.m_insets.top;
  365.          info.increaseInsetsRight(this.m_insets.right);
  366.          info.increaseInsetsLeft(this.m_insets.left);
  367.          this.m_leftRenderingArea = x + this.m_insets.left;
  368.          width -= this.m_insets.left + this.m_insets.right;
  369.          width = Math.max(0, width);
  370.          this.m_line = this.createALine(this.m_leftRenderingArea, this.m_yPos, width);
  371.          boolean bNewline = false;
  372.          this.m_layoutRows.removeAllElements();
  373.          this.m_targetWidth = Math.max(0, width - info.leftMargin - info.rightMargin);
  374.          boolean bLastNoBreakSpace = false;
  375.  
  376.          while(true) {
  377.             if (this.m_view.isPlaceHolderView()) {
  378.                this.m_pushedViews.removeAllElements();
  379.                this.pushOnViewStack(this.m_view.m_children, this.m_pushedViews);
  380.                if (this.m_pushedViews.size() > 0) {
  381.                   this.m_view = (View)this.m_viewStack.pop();
  382.                   this.m_pushedViews.removeAllElements();
  383.                }
  384.             }
  385.  
  386.             if (this.m_view.isFloater()) {
  387.                if (!bNewline && !this.m_line.isEmpty() && this.m_totalSpan != 0) {
  388.                   if (this.m_viewStack.empty()) {
  389.                      if (!this.m_line.isEmpty()) {
  390.                         this.startNewLine(width, info);
  391.                      }
  392.  
  393.                      this.layoutFloater(width, info, this.m_view);
  394.                      break;
  395.                   }
  396.  
  397.                   info.pendingFloaters.addElement(this.m_view);
  398.                   bLastNoBreakSpace = this.m_view.isNoBreakSpace();
  399.                   this.m_view = (View)this.m_viewStack.pop();
  400.                } else {
  401.                   if (!this.m_line.isEmpty()) {
  402.                      this.startNewLine(width, info);
  403.                   }
  404.  
  405.                   this.layoutFloater(width, info, this.m_view);
  406.                   if (this.m_viewStack.empty()) {
  407.                      break;
  408.                   }
  409.  
  410.                   bLastNoBreakSpace = this.m_view.isNoBreakSpace();
  411.                   this.m_view = (View)this.m_viewStack.pop();
  412.                }
  413.             } else {
  414.                if (bNewline || this.m_view.isNewlineView()) {
  415.                   bNewline = false;
  416.                   if (!this.m_line.isEmpty()) {
  417.                      this.startNewLine(width, info);
  418.                   }
  419.  
  420.                   if (this.m_view.isBlockView()) {
  421.                      this.m_line.addView(this.m_view);
  422.                      this.startNewLine(width, info);
  423.                      if (this.m_viewStack.empty()) {
  424.                         break;
  425.                      }
  426.  
  427.                      bLastNoBreakSpace = this.m_view.isNoBreakSpace();
  428.                      this.m_view = (View)this.m_viewStack.pop();
  429.                      continue;
  430.                   }
  431.                }
  432.  
  433.                if ((this.m_totalSpan == 0 || this.m_line.isEmpty()) && !this.m_view.setToLineStarter()) {
  434.                   if (this.m_viewStack.empty()) {
  435.                      break;
  436.                   }
  437.  
  438.                   this.m_view = (View)this.m_viewStack.pop();
  439.                } else {
  440.                   int span = this.m_view.getPreferredSpan(1);
  441.                   if (this.m_bCanWrap && !this.m_view.isNoBreakSpace() && !bLastNoBreakSpace && this.m_totalSpan + span > this.m_targetWidth) {
  442.                      int availSpace = this.m_targetWidth - this.m_totalSpan;
  443.                      if (this.m_view.canSplit(availSpace)) {
  444.                         View[] splits = this.m_view.split(availSpace);
  445.                         this.m_line.addView(splits[0]);
  446.                         this.startNewLine(width, info);
  447.                         this.m_view = splits[1];
  448.                      } else if (!this.m_line.isEmpty()) {
  449.                         this.startNewLine(width, info);
  450.                      } else if (this.m_view.isSplittable()) {
  451.                         View[] splits = this.m_view.split(availSpace);
  452.                         this.m_line.addView(splits[0]);
  453.                         this.startNewLine(width, info);
  454.                         if (splits[1] != null) {
  455.                            this.m_view = splits[1];
  456.                         } else {
  457.                            if (this.m_viewStack.empty()) {
  458.                               break;
  459.                            }
  460.  
  461.                            this.m_view = (View)this.m_viewStack.pop();
  462.                         }
  463.                      } else {
  464.                         if (this.m_view.isDisplayableView()) {
  465.                            this.m_line.addView(this.m_view);
  466.                         }
  467.  
  468.                         this.startNewLine(width, info);
  469.                         if (this.m_viewStack.empty()) {
  470.                            break;
  471.                         }
  472.  
  473.                         bLastNoBreakSpace = this.m_view.isNoBreakSpace();
  474.                         this.m_view = (View)this.m_viewStack.pop();
  475.                      }
  476.                   } else if (this.m_bCanWrap && this.m_totalSpan + span > this.m_targetWidth && this.canBackTrack()) {
  477.                      this.startNewLine(width, info);
  478.                      if (this.m_viewStack.empty()) {
  479.                         break;
  480.                      }
  481.  
  482.                      this.m_view = (View)this.m_viewStack.pop();
  483.                   } else if (bLastNoBreakSpace && this.m_totalSpan + span > this.m_targetWidth && this.m_view.isSplittable()) {
  484.                      int availSpace = this.m_targetWidth - this.m_totalSpan;
  485.                      View[] splits = this.m_view.split(availSpace);
  486.                      this.m_line.addView(splits[0]);
  487.                      bLastNoBreakSpace = false;
  488.                      this.startNewLine(width, info);
  489.                      if (splits[1] != null) {
  490.                         this.m_view = splits[1];
  491.                      } else {
  492.                         if (this.m_viewStack.empty()) {
  493.                            break;
  494.                         }
  495.  
  496.                         this.m_view = (View)this.m_viewStack.pop();
  497.                      }
  498.                   } else {
  499.                      if (this.m_view.isDisplayableView()) {
  500.                         this.m_line.addView(this.m_view);
  501.                      }
  502.  
  503.                      if (this.m_view.getElementType() == 7) {
  504.                         String clearAtts = (String)this.m_view.getAttribute("clear");
  505.                         if (clearAtts != null) {
  506.                            this.startNewLine(width, info);
  507.                            int yEndPosition = -1;
  508.                            if (clearAtts.equalsIgnoreCase("left")) {
  509.                               yEndPosition = info.clearLeftMargin();
  510.                            } else if (clearAtts.equalsIgnoreCase("right")) {
  511.                               yEndPosition = info.clearRightMargin();
  512.                            } else if (clearAtts.equalsIgnoreCase("all") || clearAtts.equalsIgnoreCase("both")) {
  513.                               yEndPosition = info.clearMargins();
  514.                            }
  515.  
  516.                            this.m_targetWidth = Math.max(0, width - info.leftMargin - info.rightMargin);
  517.                            if (yEndPosition != -1 && yEndPosition > this.m_yPos) {
  518.                               ViewLine emptyLine = this.createALine(this.m_leftRenderingArea, this.m_yPos, width);
  519.                               emptyLine.bounds = new Rectangle(emptyLine.x, emptyLine.y, emptyLine.lineWidth, yEndPosition - this.m_yPos);
  520.                               this.m_layoutRows.addElement(emptyLine);
  521.                               this.m_yPos = yEndPosition;
  522.                               this.m_line.y = yEndPosition;
  523.                               if (this.m_viewStack.empty()) {
  524.                                  break;
  525.                               }
  526.  
  527.                               bLastNoBreakSpace = this.m_view.isNoBreakSpace();
  528.                               this.m_view = (View)this.m_viewStack.pop();
  529.                               continue;
  530.                            }
  531.                         }
  532.                      }
  533.  
  534.                      bNewline = this.m_view.isNextViewOnNewLine();
  535.                      this.m_totalSpan += span;
  536.                      if (this.m_viewStack.empty()) {
  537.                         this.startNewLine(width, info);
  538.                         break;
  539.                      }
  540.  
  541.                      bLastNoBreakSpace = this.m_view.isNoBreakSpace();
  542.                      this.m_view = (View)this.m_viewStack.pop();
  543.                   }
  544.                }
  545.             }
  546.          }
  547.  
  548.          this.m_rows = new ViewLine[this.m_layoutRows.size()];
  549.          this.m_layoutRows.copyInto(this.m_rows);
  550.          this.m_floaters = new View[this.m_floats.size()];
  551.          this.m_floats.copyInto(this.m_floaters);
  552.  
  553.          for(int i = 0; i < this.m_rows.length; ++i) {
  554.             this.m_bounds.add(this.m_rows[i].bounds);
  555.          }
  556.  
  557.          if (this.m_alignment == 1 || this.m_alignment == 2) {
  558.             for(int j = 0; j < this.m_rows.length; ++j) {
  559.                this.m_rows[j].alignmentAdjust();
  560.             }
  561.  
  562.             if (!this.alignInBounds() && this.m_bounds.width < width) {
  563.                this.m_bounds.width = width;
  564.             }
  565.          }
  566.  
  567.          if (this.isFloaterClearer()) {
  568.             int currentYEnd = this.m_bounds.y + this.m_bounds.height;
  569.             int yEnd = info.clearMargins();
  570.             if (yEnd > currentYEnd) {
  571.                Rectangle var10000 = this.m_bounds;
  572.                var10000.height += yEnd - currentYEnd;
  573.             }
  574.          }
  575.  
  576.          Rectangle var23 = this.m_bounds;
  577.          var23.width += this.m_insets.right;
  578.          var23 = this.m_bounds;
  579.          var23.height += this.m_insets.bottom;
  580.          info.decreaseInsetsRight(this.m_insets.right);
  581.          info.decreaseInsetsLeft(this.m_insets.left);
  582.          return this.m_bounds;
  583.       }
  584.    }
  585.  
  586.    protected void layoutFloater(int parentWidth, LayoutInfo info, View view) {
  587.       LayoutInfo floaterInfo = new LayoutInfo();
  588.       floaterInfo.bPaginate = info.bPaginate;
  589.       int xOffset = view.m_alignment == 0 ? info.leftMargin : 0;
  590.       Rectangle bounds = view.layout(this.m_leftRenderingArea + xOffset, this.m_yPos, this.m_targetWidth, floaterInfo);
  591.       if (view.m_alignment == 2) {
  592.          xOffset = Math.max(0, parentWidth - info.rightMargin - bounds.width);
  593.          if (xOffset > 0) {
  594.             view.move(xOffset, 0, true);
  595.          }
  596.  
  597.          FloatStackItem item = new FloatStackItem(info.insetsRight + bounds.width, bounds.y + bounds.height);
  598.          info.pushRight(item);
  599.       } else {
  600.          FloatStackItem item = new FloatStackItem(info.insetsLeft + bounds.width, bounds.y + bounds.height);
  601.          info.pushLeft(item);
  602.       }
  603.  
  604.       this.m_targetWidth = Math.max(0, parentWidth - info.leftMargin - info.rightMargin);
  605.       this.saveFloater(view);
  606.    }
  607.  
  608.    protected void layoutPendingFloaters(int x, int width, LayoutInfo info) {
  609.       Vector leftFloaters = new Vector();
  610.       Vector rightFloaters = new Vector();
  611.  
  612.       View floater;
  613.       for(Enumeration e = info.pendingFloaters.elements(); e.hasMoreElements(); this.saveFloater(floater)) {
  614.          floater = (View)e.nextElement();
  615.          if (floater.m_alignment == 0) {
  616.             leftFloaters.addElement(floater);
  617.          } else {
  618.             rightFloaters.addElement(floater);
  619.          }
  620.       }
  621.  
  622.       int xPos = x;
  623.       int targetWidth = Math.max(0, width - info.rightMargin - info.leftMargin);
  624.       int renderingWidth = targetWidth;
  625.       Enumeration e = leftFloaters.elements();
  626.  
  627.       while(e.hasMoreElements()) {
  628.          View floater = (View)e.nextElement();
  629.          new LayoutInfo();
  630.          Rectangle bounds = floater.layout(xPos, this.m_yPos, renderingWidth, info);
  631.          xPos += bounds.width;
  632.          renderingWidth -= bounds.width;
  633.          renderingWidth = Math.max(renderingWidth, 0);
  634.          info.pushLeft(new FloatStackItem(bounds.width, bounds.y + bounds.height));
  635.       }
  636.  
  637.       xPos = x;
  638.       renderingWidth = targetWidth;
  639.       Enumeration e = rightFloaters.elements();
  640.  
  641.       while(e.hasMoreElements()) {
  642.          View floater = (View)e.nextElement();
  643.          Rectangle bounds = floater.layout(xPos, this.m_yPos, renderingWidth, new LayoutInfo());
  644.          int xOffset = Math.max(0, renderingWidth - bounds.width);
  645.          floater.move(xOffset, 0, true);
  646.          renderingWidth -= bounds.width;
  647.          renderingWidth = Math.max(renderingWidth, 0);
  648.          info.pushRight(new FloatStackItem(bounds.width, bounds.y + bounds.height));
  649.       }
  650.  
  651.       info.pendingFloaters.removeAllElements();
  652.    }
  653.  
  654.    protected synchronized void loadResources() {
  655.       for(int i = 0; i < this.m_children.length; ++i) {
  656.          this.m_children[i].loadResources();
  657.       }
  658.  
  659.    }
  660.  
  661.    protected void makeChildren(ViewFactory factory) {
  662.       int nCount = this.m_elem.getElementCount();
  663.       this.m_children = new View[nCount];
  664.  
  665.       for(int i = 0; i < nCount; ++i) {
  666.          this.m_children[i] = factory.createView(this, this.m_elem.getElementAt(i), this.m_container);
  667.       }
  668.  
  669.       for(int i = 0; i < nCount; ++i) {
  670.          this.m_children[i].makeChildren(factory);
  671.       }
  672.  
  673.    }
  674.  
  675.    protected View modelToView(int pos) {
  676.       if (pos >= this.m_elem.m_p0 && pos <= this.m_elem.m_p1) {
  677.          return this;
  678.       } else {
  679.          for(int row = 0; row < this.m_rows.length; ++row) {
  680.             View[] views = this.m_rows[row].getViews();
  681.  
  682.             for(int j = 0; j < views.length; ++j) {
  683.                View v = views[j].modelToView(pos);
  684.                if (v != null) {
  685.                   return v;
  686.                }
  687.             }
  688.          }
  689.  
  690.          return null;
  691.       }
  692.    }
  693.  
  694.    protected void move(int x, int y, boolean bMoveFloaters) {
  695.       for(int i = 0; i < this.m_rows.length; ++i) {
  696.          this.m_rows[i].move(x, y, bMoveFloaters);
  697.       }
  698.  
  699.       if (bMoveFloaters) {
  700.          Rectangle b = this.getBounds();
  701.  
  702.          for(int i = 0; i < this.m_floaters.length; ++i) {
  703.             if (this.m_floaters[i].getBounds().intersects(b)) {
  704.                this.m_floaters[i].move(x, y, bMoveFloaters);
  705.             }
  706.          }
  707.       }
  708.  
  709.       Rectangle var10000 = this.m_bounds;
  710.       var10000.x += x;
  711.       var10000 = this.m_bounds;
  712.       var10000.y += y;
  713.    }
  714.  
  715.    protected int pageBreakAdjust(LayoutInfo info) {
  716.       info.setPageBreak(this.getBounds().y);
  717.       Rectangle origBounds = new Rectangle(this.m_bounds);
  718.  
  719.       for(int row = 0; row < this.m_rows.length; ++row) {
  720.          int rowAdjustment = this.m_rows[row].pageBreakAdjust(info);
  721.          if (rowAdjustment > 0 && row != this.m_rows.length - 1) {
  722.             for(int j = row + 1; j < this.m_rows.length; ++j) {
  723.                this.m_rows[j].move(0, rowAdjustment, true);
  724.             }
  725.          }
  726.       }
  727.  
  728.       for(int i = 0; i < this.m_rows.length; ++i) {
  729.          this.m_bounds.add(this.m_rows[i].bounds);
  730.       }
  731.  
  732.       return this.m_bounds.height - origBounds.height;
  733.    }
  734.  
  735.    public void paint(Graphics g, Shape allocation) {
  736.       Rectangle clip = allocation.getBounds();
  737.       if (this.m_bounds.intersects(clip)) {
  738.          for(int row = 0; row < this.m_rows.length; ++row) {
  739.             View[] views = this.m_rows[row].getViews();
  740.  
  741.             for(int j = 0; j < views.length; ++j) {
  742.                views[j].paint(g, clip);
  743.             }
  744.          }
  745.  
  746.          if (this.m_elem.getType() == 10) {
  747.             this.drawDebugBox(g, Color.blue);
  748.          }
  749.       }
  750.  
  751.    }
  752.  
  753.    protected void paintFocusBox(Graphics g, Shape allocation) {
  754.       Rectangle clip = allocation.getBounds();
  755.       if (this.m_bounds.intersects(clip)) {
  756.          if (this.m_elem.getDrawFocusBox()) {
  757.             g.setColor(Color.black);
  758.             Utilities.drawDottedRectangle(g, this.m_bounds.x, this.m_bounds.y, this.m_bounds.width, this.m_bounds.height);
  759.          }
  760.  
  761.          for(int row = 0; row < this.m_rows.length; ++row) {
  762.             View[] views = this.m_rows[row].getViews();
  763.  
  764.             for(int j = 0; j < views.length; ++j) {
  765.                views[j].paintFocusBox(g, clip);
  766.             }
  767.          }
  768.       }
  769.  
  770.    }
  771.  
  772.    private void pushOnViewStack(View[] vws, Vector pushedViews) {
  773.       if (vws != null) {
  774.          for(int i = vws.length - 1; i >= 0; --i) {
  775.             if (vws[i] != null) {
  776.                if (vws[i].isPlaceHolderView()) {
  777.                   this.pushOnViewStack(vws[i].m_children, pushedViews);
  778.                } else {
  779.                   this.m_viewStack.push(vws[i]);
  780.                   pushedViews.addElement(vws[i]);
  781.                }
  782.             }
  783.          }
  784.       }
  785.  
  786.    }
  787.  
  788.    protected void reset() {
  789.       for(int i = 0; i < this.m_children.length; ++i) {
  790.          this.m_children[i].reset();
  791.       }
  792.  
  793.    }
  794.  
  795.    protected void saveFloater(View v) {
  796.       this.m_container.addFloater(v);
  797.       this.m_floats.addElement(v);
  798.    }
  799.  
  800.    protected void setCanWrap(boolean bWrap) {
  801.       for(int i = 0; i < this.m_children.length; ++i) {
  802.          if (!this.m_children[i].isSelfContained()) {
  803.             this.m_children[i].setCanWrap(bWrap);
  804.          }
  805.       }
  806.  
  807.       this.m_bCanWrap = bWrap;
  808.    }
  809.  
  810.    protected void setDimensions(int width, int height) {
  811.       Rectangle var10000 = this.m_bounds;
  812.       var10000.width += Math.max(0, width - this.m_bounds.width);
  813.       var10000 = this.m_bounds;
  814.       var10000.height += Math.max(0, height - this.m_bounds.height);
  815.    }
  816.  
  817.    protected void setInsets(int top, int left, int bottom, int right) {
  818.       this.m_insets.top = top;
  819.       this.m_insets.left = left;
  820.       this.m_insets.bottom = bottom;
  821.       this.m_insets.right = right;
  822.    }
  823.  
  824.    protected boolean setToLineStarter() {
  825.       return true;
  826.    }
  827.  
  828.    protected View[] split(int width) {
  829.       return null;
  830.    }
  831.  
  832.    protected void startNewLine(int width, LayoutInfo info) {
  833.       this.m_line.layout(width, this.m_targetWidth, info);
  834.       this.m_yPos += this.m_line.height + this.m_line.descent;
  835.       this.m_layoutRows.addElement(this.m_line);
  836.       if (info.pendingFloaters.size() > 0) {
  837.          this.layoutPendingFloaters(this.m_leftRenderingArea, width, info);
  838.       }
  839.  
  840.       while(info.leftMargin > 0) {
  841.          int yEnd = info.getLeftYEnd();
  842.          if (this.m_yPos < yEnd) {
  843.             break;
  844.          }
  845.  
  846.          info.popLeft();
  847.       }
  848.  
  849.       while(info.rightMargin > 0) {
  850.          int yEnd = info.getRightYEnd();
  851.          if (this.m_yPos < yEnd) {
  852.             break;
  853.          }
  854.  
  855.          info.popRight();
  856.       }
  857.  
  858.       this.m_line = this.createALine(this.m_leftRenderingArea, this.m_yPos, width);
  859.       this.m_totalSpan = 0;
  860.       this.m_targetWidth = Math.max(0, width - info.leftMargin - info.rightMargin);
  861.    }
  862.  
  863.    protected ElementViewInfo viewToModel(int x, int y) {
  864.       ElementViewInfo info = null;
  865.       Rectangle bounds = this.getBounds();
  866.       if (bounds.contains(x, y)) {
  867.          for(int row = 0; row < this.m_rows.length; ++row) {
  868.             View[] views = this.m_rows[row].getViews();
  869.  
  870.             for(int j = 0; j < views.length; ++j) {
  871.                if (views[j].contains(x, y)) {
  872.                   info = views[j].viewToModel(x, y);
  873.                   if (info != null) {
  874.                      break;
  875.                   }
  876.                }
  877.             }
  878.          }
  879.  
  880.          if (info == null) {
  881.             info = new ElementViewInfo(this.m_elem, this);
  882.          }
  883.       }
  884.  
  885.       return info;
  886.    }
  887. }
  888.